<?php

namespace App\Http\Helper;
define("CONNECTED", true);
define("DISCONNECTED", false);


 Class Socket
 {
     private static $instance;

     private static $socketCreate;

     private static $socketConnect;

     private $connection = null;

     private $connectionState = DISCONNECTED;

     private $defaultHost = "192.168.128.198";

     private $defaultPort = 9301;

     private $defaultTimeOut = 0;

     public $debug = false;


     public function __construct()
     {

     }

     /**
      * Singleton pattern. Returns the same instance to all callers
      *
      * @return Socket
      */

     public static function singleton()
     {
         if (self::$instance == null || ! self::$instance instanceof Socket)
         {
             self::$instance = new Socket();
         }

         return self::$instance;
     }

     public function connect($serverHost=false,$serverPort=false,$timeOut=false)
     {
         if($serverHost == false)
         {
             $serverHost = $this->defaultHost;
         }

         if($serverPort == false)
         {
             $serverPort = $this->defaultPort;
         }

         $this->defaultHost = $serverHost;
         $this->defaultPort = $serverPort;

         if($timeOut == false)
         {
             $timeOut = $this->defaultTimeOut;
         }

         if(!self::$socketCreate){
             echo 111;
             self::$socketCreate = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
         }

         if(!self::$socketConnect){
             echo 222;
             self::$socketConnect = socket_connect(self::$socketCreate,$serverHost,$serverPort);
         }

         return self::$socketConnect;

        /* if(!self::$socketConnect)
         {
             $errorString = socket_strerror(socket_last_error(self::$socketCreate));
             $this->_throwError("Connecting to {$serverHost}:{$serverPort} failed.<br>Reason: {$errorString}");
         }else{
             $this->_throwMsg("Socket connected!");
         }*/

        // $this->connectionState = CONNECTED;
     }


     /**
      * Disconnects from the server
      *
      * @return True on succes, false if the connection was already closed
      */

     public function disconnect()
     {
         if($this->validateConnection())
         {
             socket_close($this->connection);
             $this->connectionState = DISCONNECTED;
             $this->_throwMsg("Socket disconnected!");
             return true;
         }

         return false;
     }

     public function sendRequest($data)
     {
         if($this->validateConnection())
         {
              $result = socket_write(self::$socketCreate,$data,strlen($data));
              return $result;
         }else{
             $this->_throwError("Sending command \"{$data}\" failed.<br>Reason: Not connected");
         }

     }

     public function getResponse()
     {
         if($this->validateConnection())
         {

             if( ($ret = socket_read(self::$socketCreate,8192)) == false){
                 $this->_throwError("Receiving response from server failed.<br>Reason: Not bytes to read");
                 return false;
             } else{
                 return $ret;
            }

         }

     }


     public function isConn()
     {
         return $this->connectionState;
     }

     public function getUnreadBytes()
     {

         $info = socket_get_status(self::$socketCreate);
         return $info['unread_bytes'];

     }

     public function getConnName(&$addr, &$port)
     {
         if ($this->validateConnection())
         {
             socket_getsockname(self::$socketCreate,$addr,$port);
         }
     }

     public function waitForResponse()
     {
         if($this->validateConnection())
         {
             return socket_read(self::$socketCreate, 2048);
         }

         $this->_throwError("Receiving response from server failed.<br>Reason: Not connected");
         return false;
     }
     /**
      * Validates the connection state
      *
      * @return bool
      */
     private function validateConnection()
     {
         return (is_resource(self::$socketCreate) && (self::$socketConnect));
     }
     /**
      * Throws an error
      *
      * @return void
      */
     private function _throwError($errorMessage)
     {
         echo "Socket error: " . $errorMessage;
     }
     /**
      * Throws an message
      *
      * @return void
      */
     private function _throwMsg($msg)
     {
         if ($this->debug)
         {
             echo "Socket message: " . $msg . "\n\n";
         }
     }

     /**
      * If there still was a connection alive, disconnect it
      */
     public function __destruct()
     {
         $this->disconnect();
     }

 }
